<?php

namespace app\common\service;

use app\common\exception\BackErrorException;
use app\common\model\VideoClaim;
use app\common\model\VideoList;
use app\common\model\VideoList as VideoListModel;
use think\Exception;
use think\facade\Cache;
use think\facade\Db;

class VideoClaimService
{
    /**
     * 字幕待编辑
     * @var int
     */
    private $wordWait = 0;
    /**
     * 字幕编辑中
     * @var int
     */
    private $wordEditor = 1;
    /**
     * 提交审核中
     * @var int
     */
    private $wordAudit = 2;
    /**
     * 审核完成
     * @var int
     */
    private $wordFinish = 3;
    /**
     * 删除状态
     * @var int
     */
    private $isDelete = 1;
    /**
     * 未删除
     * @var int
     */
    private $noDelete = 0;
    /**
     * 获取指定用户的认领视频列表
     * @param $uid
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getClaimList($uid = 0)
    {
        $where['is_delete'] = 0;
        if ($uid) {
            $where['uid'] = $uid;
        }
        $res = VideoClaim::where($where)->column('video_id,create_time');
        if (!$res) {
            return [];
        }
        return $res;
    }

    /**
     * 时间是否超过1星期
     * @param $time
     * @return bool
     */
    public function isMoreThanWeek($time)
    {
        return (time() - $time) > 7 * 86400;
    }

    /**
     * 检查是否有未完成编辑的任务
     * @param $uid
     * @throws BackErrorException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function deleteVideoByTime($uid)
    {
        $redisKey = "abandonVideo::VideoClaim::Uid:".$uid;
        if (!Cache::get($redisKey)) {
            $videoClaim = VideoClaim::where(['uid' => $uid, 'is_delete' => $this->noDelete])
                ->column('create_time,video_id');
            if ($videoClaim) {
                foreach ($videoClaim as $item) {
                    if ($this->isMoreThanWeek($item['create_time']) && !$this->checkVideoFinish($item['video_id'])) {
                        $this->abandonVideoId($item['video_id'], $uid);
                    }
                }
            }
            Cache::set($redisKey, true, env('cache.expire', 86400));
        }
    }

    /**
     * 认领视频
     * @param $videoId
     * @param $uid
     * @return bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function insertClaimVideo($videoId, $uid)
    {
        app(VideoClaimService::class)->deleteVideoByTime($uid);
        if (empty($videoId) || empty($uid)) {
            throw new BackErrorException('参数有误，请检查');
        }
        //检查视频是否被认领
        if ($this->checkExistClaim($videoId)) {
            throw new BackErrorException('此视频已被人认领，请检查');
        }
        //检查视频是否存在
        if (!VideoListModel::find($videoId)) {
            throw new BackErrorException('此视频id有误，请检查');
        }
        //检查user是否存在未完成编辑字幕的视频
        if (!$this->userCheckClaim($uid)) {
            throw new BackErrorException('已存在未编辑完成的视频，请先编辑');
        }
        $insertData = [
            'video_id' => $videoId,
            'uid' => $uid,
            'create_time' => time(),
            'update_time' => time()
        ];
        $insertRes = VideoClaim::create($insertData);
        if (!$insertRes) {
            throw new BackErrorException('认领视频失败，请检查');
        }
        return true;
    }
    /**
     * 检查视频是否完成编辑
     * @param $videoId
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function checkVideoFinish($videoId)
    {
        $status = VideoList::where(['id' => $videoId, 'delete_time' => $this->noDelete])
            ->column('status');
        return current($status) == $this->wordFinish;
    }

    /**
     * 检查个人是否还能认领视频
     * @param $uid
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function userCheckClaim($uid)
    {
        //检查是否有认领视频
        $userClaimREs = VideoClaim::where(['uid' => $uid, 'is_delete'=>$this->noDelete])->field('video_id')->select();
        if (!$userClaimREs) {
            //未认领视频，返回true
            return true;
        }
        $userClaimREs = $userClaimREs->toArray();
        $videoIds = array_unique(array_column($userClaimREs, 'video_id'));
        $videoStatus = VideoList::whereIn('id', $videoIds)->field('status')->select()->toArray();
        $arrayFinish = [
            $this->wordWait,
            $this->wordAudit,
            $this->wordEditor
        ];
        $currStatus = array_column($videoStatus, 'status');
        if (!empty(array_intersect($arrayFinish, $currStatus))) {
            //存在编辑未完成的视频
            return false;
        }
        return true;
    }
    /**
     * 是否为admin
     * @param $user
     * @return bool
     */
    private function isAdmin($user)
    {
        return in_array("admin", $user['roles']);
    }

    /**
     * 放弃认领视频
     * @param $videoId
     * @param $user
     * @return bool
     * @throws BackErrorException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function abandonVideoId($videoId, $user)
    {
        if (empty($videoId)) {
            throw new BackErrorException('参数有误，请检查');
        }
        if (!$this->isAdmin($user)) {
            //不是管理员，判断权限
            if (!$this->checkExistClaim($videoId, $user['id'])) {
                throw new BackErrorException('该账号无此认领视频，请检查');
            }
        }
        $updateClaim = [
            'uid' => $user['id'],
            'video_id' => $videoId,
            'update_time' => time(),
            'is_delete' => $this->isDelete
        ];
        Db::startTrans();
        try {
            //清除字幕
            Db::table("video_wordscreen")->where(['video_id'=>$videoId])->update(['is_delete' => $this->isDelete]);
            //清除关联
            VideoClaim::where(['video_id' => $videoId])->update($updateClaim);
            //修改视频状态
            VideoList::where(['id' => $videoId])->update(['status' => $this->wordWait]);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            throw new BackErrorException($e->getMessage() ?? '删除认领失败');
        }
        return true;
    }

    /**
     * 检查视频是否已被认领
     * @param $videoId
     * @param $uid
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function checkExistClaim($videoId, $uid = 0)
    {
        $where = [
            'video_id' => $videoId,
            'is_delete' => 0
        ];
        if ($uid) {
            $where['uid'] = $uid;
        }
        $res = VideoClaim::where($where)->field('uid')->find();
        if ($res) {
            return true;
        }
        return false;
    }

}